# from enum import Enum
# from message import MSG
# import json
# from command import *
# import logging

# logger = logging.getLogger()


# class ETH_REPLY(MSG):

#     _type_check = None          # Used to check for the correct type in unpack when subclassing
#     _attr_in_reply = "result"   # Attribute name in the first name of reply,
#     _cmd_t = CMD.Type.DO_NOTHING  # cmd type bind to this reply subclass

#     _subclasses = dict()        # Holds a reference for all defined subclasses msg_id => class
#     _cmd_bind = dict()          # Holds a CMD.Type -> ETH_REPLY subclass dict.

#     class Type(Enum):
#         REPLY_GET_VERSION             = b'\x10\x01'       # 2.1.1
#         REPLY_GET_SERIAL              = b'\x10\x03'       # 2.1.2
#         REPLY_GET_PARA                = b'\x10\x04'       # 2.1.3
#         REPLY_GET_SCAN_PARA           = b'\x10\x05'       # 2.1.4
#         REPLY_GET_CH_CFG              = b'\x10\x06'       # 2.1.5
#         REPLY_SET_SCAN_PARA           = b'\x20\x01'       # 2.2.1
#         REPLY_SET_THRESHOLD           = b'\x20\x02'       # 2.2.2
#         REPLY_SET_AMPLIFY             = b'\x20\x03'       # 2.2.3
#         REPLY_SET_PEAK_INTERVAL       = b'\x20\x04'       # 2.2.4
#         REPLY_SAVE_THRESHOLD          = b'\x20\x06'       # 2.2.5
#         REPLY_STOP_SAMPLE             = b'\x30\x01'       # 2.3.1
#         REPLY_START_SAMPLE            = b'\x30\x02'       # 2.3.2
#         REPLY_START_TEST              = b'\x30\x03'       # 2.3.3
#         REPLY_START_SPEC_SAMPLE       = b'\x30\x04'       # 2.3.4
#         REPLY_GET_ONESHOT_SPEC        = b'\x30\x07'       # 2.3.5
      

#         def __str__(self) -> str:
#             return self.value

#     @classmethod
#     def add_subclass(cls, type_, cmd_type, attr="result", data_type=bool):
#         """Decorator for subclasses

#         The reply json will be like this:
#         {
#             "type" : `type_`,
#             "reply" :
#             {
#                 "`attr`" : <data in `data_type` type>
#             }
#         }

#         Parameters
#         ----------
#         type_ : `ETH_REPLY.Type`
#             Indicate the type of ETH_REPLY subclass.
#         cmd_type : `CMD.Type`
#             Indicate the type of CMD subclass reply for.
#         attr : `str`
#             Attribute name in the first name of reply.
#         data_type : `Type`
#             Type of the res data.

#         """
#         def x(subclass):
#             subclass._type_check = type_
#             cls._subclasses[type_] = subclass
#             cls._cmd_bind[cmd_type] = subclass
#             subclass._attr_in_reply = attr
#             subclass._cmd_t = cmd_type
#             return subclass
#         return x
    
#     @classmethod
#     def generate_reply(cls, cmd_type, res):
#         """Generate reply according to `cmd_type`
#         and handle `res`.

#         Parameters
#         ----------
#         cmd_type : `CMD.Type`
#             Command type to reply to.
#         res : `Any`
#             Result of the command handler.

#         Returns
#         -------
#         `bytes` | `None`
#             Returns packed eth_reply bytes for send if no exception.
#             Else returns `None`.
#         """
#         try:
#             subclass = cls._cmd_bind[cmd_type]
#             return subclass(res).pack()
#         except KeyError as e:
#             logger.error("Have not binded this type of command to a reply : %s." % cmd_type)
#             logger.exception(e)
#             return None
#         except TypeError as e:
#             logger.exception(e)
#             return None

    
#     def __init__(self, res):
#         self.type: ETH_REPLY.Type = self._type_check
#         self.reply = res

#     def pack(self) -> bytes:
#         """Pack self to a JSON `bytes` object for sending.

#         Returns
#         -------
#         bytes
#             Pakced JSON `bytes`.
#         """
#         cmd_int = self._cmd_t.value
#         if self.reply is None:          # Don't need resp like Seq wavelen transfer
#             return None
#         if type(self.reply) is list:
#             reply_payload = pack(f"!B{len(self.reply)}H", cmd_int, *self.reply)
#         elif type(self.reply) is bool:
#             reply_payload = pack(f"!BH", cmd_int, not self.reply)
#         else:
#             reply_payload = pack(f"!BH", cmd_int, self.reply)
#         bstr = b"FHD\x01\x00\x00\x00\x08" + reply_payload + b"FED"
#         return bstr


# @ETH_REPLY.add_subclass(ETH_REPLY.Type.REPLY_DO_NOTHING, CMD.Type.DO_NOTHING)
# class ETH_REPLY_DO_NOTHING(ETH_REPLY):
#     pass


# @ETH_REPLY.add_subclass(ETH_REPLY.Type.REPLY_SAVE_CONFIG, CMD.Type.SAVE_CONFIG)
# class ETH_REPLY_SAVE_CONFIG(ETH_REPLY):
#     pass


# @ETH_REPLY.add_subclass(ETH_REPLY.Type.REPLY_START_SAMPLE, CMD.Type.START_SAMPLE)
# class ETH_REPLY_START_SAMPLE(ETH_REPLY):
#     pass


# @ETH_REPLY.add_subclass(ETH_REPLY.Type.REPLY_STOP_SAMPLE, CMD.Type.STOP_SAMPLE)
# class ETH_REPLY_STOP_SAMPLE(ETH_REPLY):
#     pass

# @ETH_REPLY.add_subclass(ETH_REPLY.Type.REPLY_GET_VERSION, CMD.Type.GET_VERSION)
# class ETH_REPLY_GET_VERSION(ETH_REPLY):
#     pass


# @ETH_REPLY.add_subclass(ETH_REPLY.Type.REPLY_SET_SPEC_LENGTH, CMD.Type.SET_SPEC_LENGTH)
# class ETH_REPLY_SET_SPEC_LENGTH(ETH_REPLY):
#     pass

# @ETH_REPLY.add_subclass(ETH_REPLY.Type.REPLY_SET_THRESHOLD, CMD.Type.SET_THRESHOLD)
# class ETH_REPLY_SET_THRESHOLD(ETH_REPLY):
#     pass

# @ETH_REPLY.add_subclass(ETH_REPLY.Type.REPLY_SET_I2C, CMD.Type.SET_I2C)
# class ETH_REPLY_SET_I2C(ETH_REPLY):
#     pass

# @ETH_REPLY.add_subclass(ETH_REPLY.Type.REPLY_SET_CHANNEL_SWITCH, CMD.Type.SET_CHANNEL_SWITCH)
# class ETH_REPLY_SET_CHANNEL_SWITCH(ETH_REPLY):
#     pass

# @ETH_REPLY.add_subclass(ETH_REPLY.Type.REPLY_SET_IND_INTERVAL, CMD.Type.SET_IND_INTERVAL)
# class ETH_REPLY_SET_IND_INTERVAL(ETH_REPLY):
#     pass

# @ETH_REPLY.add_subclass(ETH_REPLY.Type.REPLY_SET_START_SPEC, CMD.Type.SET_START_SPEC)
# class ETH_REPLY_SET_START_SPEC(ETH_REPLY):
#     pass

# @ETH_REPLY.add_subclass(ETH_REPLY.Type.REPLY_SET_BULK_SIZE, CMD.Type.SET_BULK_SIZE)
# class ETH_REPLY_SET_BULK_SIZE(ETH_REPLY):
#     pass

# @ETH_REPLY.add_subclass(ETH_REPLY.Type.REPLY_GET_SPECTURE, CMD.Type.GET_SPECTURE)
# class ETH_REPLY_GET_SPECTURE(ETH_REPLY):
#     pass

# @ETH_REPLY.add_subclass(ETH_REPLY.Type.REPLY_SET_THRESHOLD_PER_POINT, CMD.Type.SET_THRESHOLD_PER_POINT)
# class ETH_REPLY_SET_THRESHOLD_PER_POINT(ETH_REPLY):
#     pass

# @ETH_REPLY.add_subclass(ETH_REPLY.Type.REPLY_GET_I2C, CMD.Type.GET_I2C)
# class ETH_REPLY_GET_I2C(ETH_REPLY):
#     pass